#include "pattern.h"
#include <boost/bind.hpp>
#include <iostream>
#include <cstdlib>
#include "event.h"
using namespace std;
using namespace boost;

Pattern::Pattern(const string &name, int number, int length)
: m_name(name), m_number(number) {
     setLength(length);
}

Pattern::~Pattern() {
     // delete events
     for (size_t i=0; i<m_events.size(); i++) {
	  if (m_events[i])
	       delete m_events[i];
     }
}

const string &Pattern::name() const {
     return m_name;
}

void Pattern::setName(const string &name) {
     m_name = name;
}

int Pattern::number() {
     return m_number;
}

void Pattern::setNumber(int number) {
     m_number = number;
}

int Pattern::length() {
     return m_events.size();
}

void Pattern::setLength(int length) {
     if (length >= (int)m_events.size()) {
	  int newcount = length-m_events.size();
	  for (int i=0; i<newcount; i++)
	       addEvent(new Event(), i);
     }
}

Event *Pattern::eventAt(int i) {
     if ((size_t)i<m_events.size())
	  return m_events.at(i);
     return NULL;
}

void Pattern::setEventAt(int i, Event *pEvent) {
     if (i >= length())
	  setLength(i+1);
     m_events[i] = pEvent;
}

void Pattern::zap() {
     for (size_t i=0; i<m_events.size(); i++) {
	  if (m_events[i]) {
	       delete m_events[i];
	       m_events[i] = NULL;
	  }
     }
}

void Pattern::addEvent(Event *pEvent, int i) {
     pEvent->setIndex(m_events.size());
     m_events.push_back(pEvent);
     // connect to event's onChange slot
     pEvent->onChange(bind(&Pattern::eventChanged, this, _1));
}

void Pattern::eventChanged(int num) {
     m_onChange(this, num);
}

signals2::connection Pattern::onChange(const OnChange::slot_type &callback) {
     return m_onChange.connect(callback);
}
